<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/


/**
 * Login Controller
 *
 * Handle logins for AIR2, displaying the login page and authenticating
 * usernames and passwords.
 *
 * @author pkarman
 * @package default
 */
class Login_Controller extends AIR2_Controller {

    /**
     * Override begin() to prevent AIR2_Controller authz from occurring
     */
    public function begin() {

    }


    /**
     * Loads login view and authenticate users
     */
    public function index() {
        // we do explicit load->view calls here
        // because the login screen is independent
        // of the rest of the View architecture.
        $req_method = $this->input->server('REQUEST_METHOD');

        // redirect to original request, or home page
        $back = $this->input->get_post('back');
        if (!isset($back) || !strlen($back)) {
            $back = site_url('');
        }

        $stash = array(
            'static_url'    => site_url(),
            'back'          => $back,
        );

        if ($req_method == 'GET') {

            // special case.
            // if we are configured to trust the PIN SSO tkt (auth_tkt)
            // then check for it and use its "sso" data value
            // as the AIR2 username
            if (AIR2_TRUST_PIN_SSO) {
                $tkt = $this->input->cookie(AIR2_PIN_SSO_TKT);
                if (!$tkt) {
                    $tkt = $this->input->get_post(AIR2_PIN_SSO_TKT);
                }
                if ($tkt) {
                    $at = new Apache_AuthTkt(array(
                            'conf'          => AIR2_PIN_SSO_CONFIG,
                            'encrypt_data'  => false,
                        )
                    );
                    //Carper::carp("got auth_tkt for trust pin sso");
                    if ($at->validate_ticket($tkt)) {
                        $tkt_info = $at->parse_ticket($tkt);
                        $tkt_data = json_decode($tkt_info['data'], true);
                        if (isset($tkt_data['sso'])) {
                            $username = $tkt_data['sso'];
                            $user = $this->_fetch_user($username);
                            if ($user) {

                                // trust prior authentication. create the AIR2 tkt.
                                $this->airuser->create_tkt($user);

                                //echo "Location: $back\n";
                                redirect($back);
                            }
                        }
                    }
                    //Carper::carp("tkt invalid");
                }
            }

            // print form
            $this->load->view('login', $stash);
        }
        elseif ($req_method == 'POST') {

            // process form
            $username = $this->input->post('username');
            $password = $this->input->post('password');

            // didn't enter username or password
            if (!$username || !$password || strlen($username) < 1
                || strlen($password) < 1) {
                $stash['errormsg'] = 'You must enter both a username and password';
                $this->load->view('login', $stash);
                return;
            }

            $user = $this->_fetch_user($username);
            
            //Carper::carp("fetched user for $username ; exists=" . $user->exists());

            // bad username
            if (!$user || !$user->exists()) {
                if ($this->response_view == "json") {
                    header('X-AIR2: authentication failed', false, 401);
                    $resp = array('success' => false, 'message' => 'authentication failed');
                    print json_encode($resp);
                    return;
                }
                elseif ($this->response_view == "xml") {
                    header('X-AIR2: authentication failed', false, 401);
                    print "<air2><success>false</success><message>authentication failed</message></air2>";
                    return;
                }
                else {
                    $stash['errormsg'] = 'The information you entered does not match an active account';
                    $this->load->view('login', $stash);
                    return;
                }
            }

            // bad password
            if (!$user->check_password($password)) {
                if ($this->response_view == "json") {
                    header('X-AIR2: authentication failed', false, 401);
                    $resp = array('success' => false, 'message' => 'authentication failed');
                    print json_encode($resp);
                    return;
                }
                elseif ($this->response_view == "xml") {
                    header('X-AIR2: authentication failed', false, 401);
                    print "<air2><success>false</success><message>authentication failed</message></air2>";
                    return;
                }
                else {
                    $stash['errormsg'] = 'The information you entered does not match an active account';
                    $this->load->view('login', $stash); //TODO -- form error msg
                    return;
                }
            }
            
            //Carper::carp("password check ok");

            // authenticated ok. create the tkt.
            $tkt = $this->airuser->create_tkt($user);
            
            //Carper::carp("tkt ok " . var_export($tkt,true));

            // non-html response does not redirect
            if ($this->response_view == "json") {
                $tkt['success'] = true;
                print json_encode($tkt);
                return;
            }
            elseif ($this->response_view == "xml") {
                header('X-AIR2: authentication failed', false, 401);
                print "<air2><success>true</success><air2_tkt>".$tkt['air2_tkt']."</air2_tkt></air2>";
                return;
            }
            else {

                //echo "Location: $back\n";
                //Carper::carp("redirect to $back");
                redirect($back);

            }
        }

    }



    /**
     *
     *
     * @param unknown $username
     * @return unknown
     */
    private function _fetch_user($username) {
        // get user from DB
        $user = AIR2_Query::create()
        ->from('User u')
        ->where('u.user_username = ?', $username)
        ->leftJoin('u.UserOrg o')
        ->leftJoin('o.AdminRole a')
        ->fetchOne();
        return $user;
    }


}
